#include <sstream>
#include "icache/avi_frame_id.h"
#include "icache/avi_reader.h"
#include "mswin/file_dir.h"

namespace icache {

#define avi_frame_desc_header "AVI frame: (fullpath to avi, its duration, frame number)"

avi_frame_id::avi_frame_id(avi_reader const & r, int n) : 
	frame_num(n), avi_fullpath(r.fullpath()), avi_duration(r.duration()), cache_on_disc_(!r.all_keyframes())
	{ }

bool avi_frame_id::equal(const item_id & i) const 
{
	const avi_frame_id * rhs = dynamic_cast<const avi_frame_id *>(&i);
	if (rhs == 0) 
		return false;
	return 
		frame_num == rhs->frame_num &&
		avi_fullpath == rhs->avi_fullpath &&
		avi_duration == rhs->avi_duration;
}

std::string avi_frame_id::name() const 
{
	std::ostringstream s;
	s << mswin::basename(avi_fullpath) << '.';
	s.width(6);
	s.fill('0');
	s << frame_num;
	return s.str();
}

static std::ostream & serialize_id(std::ostream & o, int frame_num, string const & f, int duration)
{
	return o << 
		avi_frame_desc_header "\n" <<
		f << '\n' << duration << '\n' << frame_num << '\n';
}

void avi_frame_id::serialize(std::ostream & o) const 
{
	serialize_id(o, frame_num, avi_fullpath, avi_duration);
}

void avi_frame_id::load(byte_image & im) const
	{ assert(!"n/a"); }

void avi_frame_id::request() const
	{ assert(!"use child class avi_frame_request"); }

bool avi_frame_id::cache_on_disc() const 
	{ return cache_on_disc_; }

//avi_frame_request

void avi_frame_request::request() const
	{ reader.request_and_wait(frame_num, desired, priority); }

icache::item_id_sptr avi_frame_id_deserializer::parse(std::istream & i) const
{
	string header;
	getline(i, header);
	string avi_fullpath;
	getline(i, avi_fullpath);
	int avi_duration;
	i >> avi_duration;
	int frame_num;
	i >> frame_num;
	if (header != avi_frame_desc_header || i.fail())
		return item_id_sptr();
	return item_id_sptr(
		new avi_frame_id(frame_num, avi_fullpath, avi_duration,
			true)); //cache_on_disc = true, because it was loaded from disc
}

} //namespace icache
